package com.na.flipcard.ui;

import static com.na.flipcard.util.GameConfigEx.RES_BUTTON_PAUSE;
import static com.na.flipcard.util.GameConfigEx.RES_BUTTON_SELECTED;
import static com.na.flipcard.util.GameConfigEx.RES_TIME_BARS;
import static com.na.flipcard.util.GameConfigEx.RES_TIME_SLOT;
import android.graphics.Color;
import android.graphics.Rect;
import android.view.MotionEvent;

import com.na.flipcard.Effect;
import com.na.flipcard.Game;
import com.na.flipcard.props.DoubleScore;
import com.na.flipcard.util.GameConfigEx;
import com.na.flipcard.util.NormalEventListener;
import com.na.flipcard.widget.GameEntry;
import com.na.game.GameManager;
import com.na.game.event.Updater;
import com.na.game.event.impl.EventAdapter;
import com.na.game.event.impl.KeyEvent;
import com.na.game.event.impl.TouchEvent;
import com.na.game.graphics.Graphics;
import com.na.game.graphics.Image;
import com.na.game.graphics.Painter;
import com.na.game.props.GameProps;
import com.na.game.props.PropsManager;
import com.na.game.resource.ResourceManager;
import com.na.game.sound.SoundManager;
import com.na.game.ui.UI;
import com.na.game.util.GameConfig;
import com.na.game.util.Util;
import com.na.game.widget.Layout;
import com.na.game.widget.Widget;
import com.na.game.widget.impl.Button;
import com.na.game.widget.impl.Container;
import com.na.game.widget.impl.GridPanel;
import com.na.game.widget.impl.Label;
import com.na.game.widget.impl.TimerLabel;

public class GameUI extends UI {

	private Game game;
	private TimerLabel timerLbl;
	private GameEntry[] gameEntrys;
	
	@Override
	public void init() {
		game = new Game(this, GameConfigEx.GAME_TIME_LIMIT);
		
		Container ui = new Container();
		ui.setBound(0, 0, GameConfig.STANDARD_WIDTH, GameConfig.STANDARD_HEIGHT);
		setWidget(ui);
		ui.setPainter(new Painter() {
			Image bg = GameManager.get(ResourceManager.class).getImageFromAssets(GameConfigEx.RES_GAME_BG);
			Rect src = new Rect(0, 0, bg.getWidth(), bg.getHeight());
			Rect dst = new Rect(0, 0, GameConfig.STANDARD_WIDTH, GameConfig.STANDARD_HEIGHT);
			@Override
			public void paint(Graphics g) {
				g.drawImage(bg, src, dst);
			}
		});
		
		// timer
		Image background = GameManager.get(ResourceManager.class).getImageFromAssets(RES_TIME_SLOT);
		Image bar = GameManager.get(ResourceManager.class).getImageFromAssets(RES_TIME_BARS);
		timerLbl = new TimerLabel(background, bar, GameConfigEx.GAME_TIME_LIMIT, 30);
		timerLbl.setUpdater(new Updater() {
			@Override
			public void update() {
				timerLbl.update(game.getTimeRemain(), game.getTimeLimit());
			}
		});
		ui.addChild(timerLbl);
		timerLbl.setBound(60, 20, bar.getWidth(), 60);
		
		// score
		final Label score = new Label("得分: 0", true, 0xFFFF0000, 0xFFFFFFFF, 40);
		score.setUpdater(new Updater() {
			@Override
			public void update() {
				score.setText("得分: " + game.getScoreTxt());
			}
		});
		ui.addChild(score);
		score.setBound(60, 70, Util.getTextWidth("score: 99999999", 40), Util.getTextHeight("H", 40));
		
		// level
		final Label level = new Label(null, true, Color.WHITE, Color.RED, 30);
		level.setUpdater(new Updater() {
			@Override
			public void update() {
				level.setText("Level: " + game.getLevel());
			}
		});
		ui.addChild(level);
		level.setBound(360, 20, 200, Util.getTextHeight("Level 13"));
		
		// pause
		Image pauseImg = GameManager.get(ResourceManager.class).getImageFromAssets(RES_BUTTON_PAUSE);
		Button pause = new Button(pauseImg);
		ui.addChild(pause);
		pause.setEventListener(new PauseListener());
		pause.setBound(GameConfig.STANDARD_WIDTH - pauseImg.getWidth() - 20, 20, pauseImg.getWidth(), pauseImg.getHeight());
		
		// main area
		final int w = 128 * 5 + 2 * 6;
		final int h = 128 * 7 + 2 * 8;
		final int x = (GameConfig.STANDARD_WIDTH - w) >> 1;
		final int y = (GameConfig.STANDARD_HEIGHT - h) / 2 - 20;
		final GridPanel gp = new GridPanel(7, 5);
		gp.setPainter(new Painter() {
			@Override
			public void paint(Graphics g) {
				g.setClip(x - 20, y - 20, w + 40, h + 40);
				g.setColor(0x33000000);
				g.fillRoundRect(x - 20, y - 20, w + 40, h + 40, 20, 20);
			}
		});
		gp.setGap(2, 2);
		ui.addChild(gp);
		gp.setBound(x, y, w, h);
		Image focus = GameManager.get(ResourceManager.class).getImageFromAssets(RES_BUTTON_SELECTED);
		gameEntrys = new GameEntry[34];
		for (int i = 0; i < 34; i++) {
			GameEntry ge = new GameEntry(i, focus, game);
			gp.addChild(ge);
			gameEntrys[i] = ge;
		}
		gp.doLayout();
		
		// tools
		GameProps[] gps = GameManager.get(PropsManager.class).getProps();
		final int w1 = 128 * 4 + 10 * 5;
		final int h1 = 128;
		final int x1 = (GameConfig.STANDARD_WIDTH - w1) >> 1;
		final int y1 = GameConfig.STANDARD_HEIGHT - h1 - 25;
		final Container toolsCntnr = new Container();
		ui.addChild(toolsCntnr);
		toolsCntnr.setBound(x1, y1, w1, h1);
		toolsCntnr.setPainter(new Painter() {
			@Override
			public void paint(Graphics g) {
				g.setColor(0x33000000);
				g.setClip(x1 - 10, y1 - 10, w1 + 20, h1 + 20);
				g.fillRoundRect(x1 - 10, y1 - 10, w1 + 20, h1 + 20, 20, 20);
			}
		});
		int offset = 10;
		int w2 = 128;
		int h2 = 128;
		int x2 = offset;
		int y2 = 0;
		for (int i = 0; i < 4; i++) {
			Button tool = new Button(new Image[1]);
			toolsCntnr.addChild(tool);
			if (i < gps.length) {
				gps[i].setExtra(game); // mark
				tool.setImage(gps[i].getIcon(), 0);
				tool.setEventListener(new ToolListener(gps[i]));
				tool.setPainter(new ToolPainter(tool, gps[i]));
				tool.setBound(x2, y2, w2, h2);
				if (gps[i] instanceof DoubleScore) {
					game.hold = (Effect) gps[i];
				}
			} else {
				tool.setImage(focus, 0);
				tool.setScaled(true);
				tool.setSrcRect(new Rect(0, 0, focus.getWidth(), focus.getHeight()));
				tool.setBound(x2 - 12, y2 - 12, w2 + 24, h2 + 24);
			}
			x2 += w2 + offset;
		}
	}
	
	@Override
	public boolean onKey(KeyEvent event) {
		if (event.action == android.view.KeyEvent.ACTION_UP && event.keyCode == android.view.KeyEvent.KEYCODE_BACK) {
			game.pause();
			return true;
		}
		return false;
	}

	@Override
	public void update() {
		super.update();
		game.update();
	}
	
	public void syncUI() {
		for (GameEntry ge : gameEntrys) {
			ge.syncUI(game);
		}
	}
	
	class ToolPainter implements Painter {
		private Widget src;
		private GameProps props;
		ToolPainter(Widget src, GameProps props) {
			this.src = src;
			this.props = props;
		}
		@Override
		public void paint(Graphics g) {
			int oldSize = g.getTextSize();
			g.setTextSize(GameConfigEx.TEXT_SIZE_SMALL);
			g.setColor(Color.RED);
			g.drawString(String.valueOf(props.getAmount()), src.getAbsBound().right, src.getAbsBound().bottom, Layout.BOTTOM_RIGHT);
			g.setTextSize(oldSize);
		}
	}
	
	class ToolListener extends EventAdapter {
		private GameProps props;
		ToolListener(GameProps props) {
			this.props = props;
		}
		@Override
		public boolean onTouch(TouchEvent event) {
			switch (event.action) {
				case MotionEvent.ACTION_DOWN:
					if (props.getAmount() > 0)
						GameManager.get(SoundManager.class).play(GameConfigEx.RES_SOUND_CLICK2);
					else
						GameManager.get(SoundManager.class).play(GameConfigEx.RES_SOUND_CLICK_BAN);
					break;
				case MotionEvent.ACTION_UP:
					GameManager.get(PropsManager.class).useProps(props.getName());
					break;
			}
			return true;
		}
	}
	
	class PauseListener extends NormalEventListener {
		@Override
		public boolean onTouch(TouchEvent event) {
			super.onTouch(event);
			if (event.action == MotionEvent.ACTION_UP) {
				game.pause();
			}
			return true;
		}
	}

}
